import os
import random
from communication import *

class FileManager:
  def __init__(self, pman, workingdir = os.getcwd()+"/"):
    self._dir = workingdir
    self._pman = pman
    self._flist = []
    self._nflists = []
    self._changelist = []
    self._change = 0
    
  def __getattr__(self, name):
    if name == "dir":
      return self._dir
    elif name == "pman":
      return self._pman
    elif name == "flist":
      return self._flist
    elif name == "nflists":
      return self._nflists
    elif name == "change":
      return self._change
    elif name == "changelist":
      return self._changelist
    
  def find(self, name):
    for fname, fsize in self._flist:
      if name == fname:
        return self._pman.plist[0]
    
    for nname, nflist in self._nflists:
      for fname, fsize in nflist:
        if fname == name:
          return self._pman.neighborsbyname(nname)
        
    return None
      
  def write_file(self, fname, data):
    file = open(self._dir + fname, "w")
    file.write(data)
      
  def fileget(self, ip, port, fname):
    comm(ip, port, self._pman.name, GET, (fname, self._pman.plist[0]))

  def processchangelist(self, name, changelist):
    name, nflist = self.getnflist(name)
    for filetuple, change in changelist:
      if change == ADDED:
        if filetuple not in nflist:
          nflist.append(filetuple)
      elif change == REMOVED:
        if filetuple in nflist:
          nflist.remove(filetuple)
				
  def getnflist(self, neighborname):
    for nflist in self._nflists:
      if nflist[0] == neighborname:
        return nflist
    return None
    
  def getstructflist(self):
    result = [[fil, self._pman.name] for fil in self._flist]
    
    def isin(fil, res = result):
      for entry in res:
        if entry[0] == fil:
          return entry
      return None
    
    for name, nflist in self._nflists:
      for fil in nflist:
        entry = isin(fil)
        if entry is not None:
          entry.append(name)
        else:
          result.append([fil, name])
    return result
      
  def addnflist(self, name, nflist):
    for nfl in self._nflists:
      if nfl[0] == name:
        self._nflists.remove(nfl)
        break
    self._nflists.append((name, nflist))
  
  def remove_nflist(self, name):
    for l in self._nflists:
      if name == l[0]:
        self._nflists.remove(l)
        break
  
  def addfile(self, filename):
    filetuple = filename, os.stat(self._dir + filename).st_size
    self._flist.append(filetuple)
    self.changemade(filetuple, ADDED)
    
  def removefile(self, filetuple):
    removed = 0
    for f in self._flist:
      if f == filetuple:
        self._flist.remove(f)
        removed = 1
        break
    if removed:
      self.changemade(filetuple, REMOVED)
  	
  def changemade(self, filetuple, change):
    thechange = (filetuple, change)
    self._changelist.append(thechange)
    self._change = 1
  	
  def sent(self):
    self._changelist = []
    self._change = 0
    
def addrandom(fman):
  files = os.listdir(fman._dir)
  if len(files) != 0:
    amount = random.randint(1, len(files))
    for i in range(amount):
      fman.addfile(files[i])
  else:
    print "Directory is empty"
